package com.zz.common.protocol;

import com.zz.common.annotation.Protocol;
import com.zz.common.config.Constants;
import com.zz.common.entity.Meta;
import com.zz.common.enums.MessageType;
import com.zz.common.enums.SerializationType;
import com.zz.common.exception.TunnelException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * 客户端与服务端默认交换协议
 */
@Slf4j
@Getter
@Setter
@Protocol
public class DefaultProtocol extends TunnelProtocol {

    /**
     * 序列化类型
     */
    private byte serializationType = SerializationType.PROTOSTUFF.getCode();

    /**
     * 元数据
     */
    private Meta meta;

    public void setType(byte type) {
        if (!MessageType.markTypeVerify(type)) {
            log.error("error is not auth");
            return;
        }
        super.setType(type);
    }

    public static Builder builder() {
        return new Builder();
    }

    public static boolean isSuccess(DefaultProtocol protocol) {
        if (protocol.getType() != MessageType.C_TYPE_AUTH.getMark()) {
            log.error("error is not auth");
            throw new TunnelException("auto is type error");
        }
        return Constants.Strings.SUCCESS.equals(protocol.getHeader());
    }

    public static class Builder {
        private byte type;
        private long serialNumber;
        private String header;
        private byte[] data;
        private Meta meta;
        private byte serializationType;

        public Builder type(MessageType type) {
            this.type = type.getMark();
            return this;
        }

        public Builder serialNumber(long serialNumber) {
            this.serialNumber = serialNumber;
            return this;
        }

        public Builder header(String header) {
            this.header = header;
            return this;
        }

        public Builder data(byte[] data) {
            if (data != null) {
                this.data = data;
            }
            return this;
        }

        public Builder() {
        }

        public Builder meta(Meta meta) {
            this.meta = meta;
            return this;
        }

        public Builder serializationType(SerializationType serializationType) {
            this.serializationType = serializationType.getCode();
            return this;
        }

        public Builder serializationType(byte serializationType) {
            this.serializationType = serializationType;
            return this;
        }

        public DefaultProtocol build() {
            DefaultProtocol protocol = new DefaultProtocol();
            protocol.setType(type);
            protocol.setSerialNumber(serialNumber);
            protocol.setHeader(header);
            protocol.setData(data);
            protocol.setMeta(meta);
            return protocol;
        }
     }

}
